package states;

import java.sql.SQLException;

import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

import entity.Pokemon;

import ui.core.Button;
import utils.ResourceManager;
import utils.SaveManager;

public class BattleState extends InGameState {

	public static final int ID = 4;
	final int INTRO_BATTLE = 0;
	final int PLAYER_TURN = 1;
	final int CHOOSE_ATTACK = 2;
	final int PLAYER_TURN_ANIMATION = 3;
	final int ENEMY_TURN = 4;
	final int ENEMY_CHOOSE = 5;
	final int GET_EXPERIENCE = 6;
	final int LEAVE_BATTLE = 7;
	final int CAPTURE = 8;
	boolean captureFlag = false;
	static StateBasedGame game;
	Pokemon enemyPokemon;
	private static int battleStage = 0;
	Button attackButton;
	Button runButton;
	Button captureButton;
	Button abilitie1Button;
	Button abilitie2Button;
	Image playerPokemonImage;
	Image enemyPokemonImage;
	Image battleBackground;
	Image menuBackground;
	Image redBackground;
	Font mediumFont;
	Font tinyFont;
	boolean flag = false;
	SaveManager svManager = new SaveManager();
	
	public void initBattle() throws SQLException {
		// Gerando a raridade
		// 0.1% de chance de vir um pokemon lendario
		// 5% de ter a chance de vir um raro
		// 8% de ter a chance vir um evoluido 2
		// 10% de ter a chance vir um evoluido 1
		// 90% de ter a chance de vir um lixo.
		captureFlag = false;
		int rarity = (int) Math.floor((Math.random() * 1000));
		if(rarity < 1){
			rarity = 1;
		}else if(rarity < 50){
			rarity = 40;
		}else if(rarity < 80){
			rarity = 70;
		}else if(rarity < 100){
			rarity = 110;
		}else{
			rarity = 250;
		}
		
		// Diminui 4 lvs do lv do pokemon do player, e adiciona de 0 a 8 levels.
		// Ou seja, pode gerar pokemons de 4 lvs +/-
		int enemy_lv;
		if (player.getFirstPokemon().getLevel() < 5) {
			enemy_lv = player.getFirstPokemon().getLevel()
					+ (int) Math.floor((Math.random() * 2));
			;
		} else {
			enemy_lv = player.getFirstPokemon().getLevel() - 4
					+ (int) Math.floor((Math.random() * 8));
		}

		enemyPokemon = new Pokemon();
		enemyPokemon = svManager.getPokemonAtributes((int)Math.random()*49);
		enemyPokemon.setLevel(enemy_lv);
		
		battleStage = INTRO_BATTLE;
		playerPokemonImage = ResourceManager.getImage(Integer.toString(player
				.getFirstPokemon().getId()) + "back");
		enemyPokemonImage = ResourceManager.getImage(Integer
				.toString(enemyPokemon.getId()) + "front");
		System.out.println("Id - " + enemyPokemon.getId());
		System.out.println("HP - " + enemyPokemon.getHp());
		System.out.println("Name - " + enemyPokemon.getName());
		System.out.println("Level - " + enemyPokemon.getLevel());
		System.out.println("Attack - " + enemyPokemon.getAttack());
		System.out.println("Defesa - " + enemyPokemon.getDefence());
		System.out.println("Velocidade - " + enemyPokemon.getSpeed());
		System.out.println("Exp - " + enemyPokemon.getExpGain());
		System.out.println("Rarity - " + enemyPokemon.getRarity());
	}
	
	public void playerAttack() {
		if(enemyPokemon.getHp()/enemyPokemon.getCurrentHp() >= enemyPokemon.getHp()/10){
			captureFlag = true;
		}
		if (battleStage == PLAYER_TURN) {		
			enemyPokemon.setCurrentHp(enemyPokemon.getCurrentHp() - 5);
			if (enemyPokemon.getCurrentHp() > 0) {
				battleStage = ENEMY_CHOOSE;
							
			} else {
				enemyPokemon.setCurrentHp(0);
				player.getFirstPokemon().adicionarExperiencia(
						enemyPokemon.getExpGain()
								/ player.getFirstPokemon().getLevel()*2);
			}

		} else if (battleStage == ENEMY_TURN) {			
			player.getFirstPokemon().setCurrentHp(
					player.getFirstPokemon().getCurrentHp() - 5);
			if (player.getFirstPokemon().getCurrentHp() > 0) {
				battleStage = PLAYER_TURN;
			} else {
				battleStage = LEAVE_BATTLE;
				player.getFirstPokemon().setCurrentHp(0);
			}
		}
	}

	@Override
	public void init(GameContainer container, StateBasedGame game) {
		BattleState.game = game;
		mediumFont = ResourceManager.getFont("dejavuNormalFont");
		tinyFont = ResourceManager.getFont("dejavuTinyFont");
		menuBackground = ResourceManager.getImage("emptyButtonNormalImage");
		battleBackground = ResourceManager.getImage("battleBackground");
		redBackground = ResourceManager.getImage("redBackground");
		
		attackButton = new Button(container,
				ResourceManager.getImage("attackButtonNormalImage"), 30, 420);
		attackButton.setMouseOverImage(ResourceManager
				.getImage("attackButtonOverImage"));
		attackButton.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				battleStage = CHOOSE_ATTACK;
			}
		});
		runButton = new Button(container,
				ResourceManager.getImage("runButtonNormalImage"), 30, 490);
		runButton.setMouseOverImage(ResourceManager
				.getImage("runButtonOverImage"));
		runButton.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				BattleState.game.enterState(InGameState.ID,
						new FadeOutTransition(Color.black),
						new FadeInTransition(Color.black));
			}
		});
		abilitie1Button = new Button(container,
				ResourceManager.getImage("emptyButtonNormalImage"), 30, 420);
		abilitie1Button.setMouseOverImage(ResourceManager
				.getImage("emptyButtonOverImage"));
		abilitie1Button.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				battleStage = PLAYER_TURN;
				playerAttack();
			}
		});
		
		abilitie2Button = new Button(container,
				ResourceManager.getImage("emptyButtonNormalImage"), 30, 500);
		abilitie2Button.setMouseOverImage(ResourceManager
				.getImage("emptyButtonOverImage"));
		abilitie2Button.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				battleStage = PLAYER_TURN;
				playerAttack();
			}
		});
		captureButton = new Button(container,
				ResourceManager.getImage("captureButtonNormalImage"), 250, 420);
		captureButton.setMouseOverImage(ResourceManager
				.getImage("captureButtonOverImage"));
		captureButton.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {					
					double chance = Math.random();
					if(chance < 0.25){
						battleStage = CAPTURE;
						try {
							player.getPokemonList().set(0, svManager.getPokemonAtributes(enemyPokemon.getId()));
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}else{
						System.out.println("Fail");
						battleStage = ENEMY_TURN;
						playerAttack();
					}
			}
		});
		try {
			initBattle();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g)
			throws SlickException {
		battleBackground.draw(0, 0);
		//caixa do inimigo
		menuBackground.draw(50, 50, 280, 60);
		//nome + lv
		mediumFont.drawString(60, 60, enemyPokemon.getName() + "  Lv: " + enemyPokemon.getLevel(), new Color(0,0,0));
		//Texto Hp
		tinyFont.drawString(80, 85, "Hp", new Color(255,0,0));
		//caixa de hp
		menuBackground.draw(110, 90, 200, 10);
		//hp atual
		redBackground.draw(113, 91, ((float)enemyPokemon.getCurrentHp()/(float)enemyPokemon.getHp()) * 195, 8);
				
		//caixa do player
		menuBackground.draw(350, 270, 280, 80);
		//nome + lv
		mediumFont.drawString(360, 280, player.getFirstPokemon().getName() + "  Lv: " + player.getFirstPokemon().getLevel(), new Color(0,0,0));
		//Texto Hp
		tinyFont.drawString(380, 305, "Hp", new Color(255,0,0));
		//caixa de hp
		menuBackground.draw(410, 310, 200, 10);
		//hp em numeros
		mediumFont.drawString(430, 322,
				Integer.toString(player.getFirstPokemon().getCurrentHp())+"/"+player.getFirstPokemon().getHp(), new Color(0,0,0));
		//hp atual
		redBackground.draw(413, 311, ((float)player.getFirstPokemon().getCurrentHp()/(float)player.getFirstPokemon().getHp()) * 195, 8);
		
		//desenhando as imagens dos pokemons
		playerPokemonImage.draw(30, 235, (float) 2);		
		enemyPokemonImage.draw(420, 100, (float) 2);
		menuBackground.draw(3, 358, 635, 275);
			
		if (player.getFirstPokemon().getCurrentHp() <= 0) {
			mediumFont.drawString(20, 410, "You Lose.", new Color(0, 0, 0));
			tinyFont.drawString(520, 410, "[Press space]", new Color(255, 0, 0));
			battleStage = LEAVE_BATTLE;
		} else if (enemyPokemon.getCurrentHp() <= 0) {
			mediumFont.drawString(20, 410,
					"You gained "
					
							+ (enemyPokemon.getExpGain() / player.getFirstPokemon()
									.getLevel()) + " experience.", new Color(0,
							0, 0));
			tinyFont.drawString(520, 410, "[Press space]", new Color(255, 0, 0));
			battleStage = GET_EXPERIENCE;
		} else if (battleStage == INTRO_BATTLE) {
			mediumFont.drawString(20, 410, "A wild " + enemyPokemon.getName()
					+ " appeared!", new Color(0, 0, 0));
			tinyFont.drawString(520, 410, "[Press space]", new Color(255, 0, 0));
		}else if (battleStage == PLAYER_TURN
				&& player.getFirstPokemon().getCurrentHp() > 0) {
			attackButton.render(container, g);
			runButton.render(container, g);
			if(captureFlag){
				captureButton.render(container, g);
			}			
		}else if (battleStage == CHOOSE_ATTACK) {
			abilitie1Button.render(container, g);
			abilitie2Button.render(container, g);
			mediumFont.drawString(40, 430, player.getFirstPokemon().getAbilitie1(), new Color(0,12,255));
			mediumFont.drawString(40, 510, player.getFirstPokemon().getAbilitie2(), new Color(0,12,255));
		}else if(battleStage == ENEMY_CHOOSE){
			mediumFont.drawString(20, 410, "Wait for enemy turn", new Color(0,0,0));
			tinyFont.drawString(520, 410, "[Press space]", new Color(255, 0, 0));			
		}else if(battleStage == CAPTURE){
			mediumFont.drawString(20, 410, "Pokemon captured with success", new Color(0,0,0));
			tinyFont.drawString(520, 410, "[Press space]", new Color(255, 0, 0));
		}
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		Input input = container.getInput();

		if (input.isKeyPressed(Input.KEY_ESCAPE)) {
			game.enterState(InGameState.ID, new FadeOutTransition(Color.black),
					new FadeInTransition(Color.black));
		}
		if (input.isKeyPressed(Input.KEY_SPACE)) {
			if (battleStage == INTRO_BATTLE) {
				battleStage = PLAYER_TURN;
			}else if (battleStage == ENEMY_CHOOSE) {
				battleStage = ENEMY_TURN;
				playerAttack();	
			}else if (battleStage == GET_EXPERIENCE
					|| battleStage == LEAVE_BATTLE || battleStage == CAPTURE) {
				game.enterState(InGameState.ID, new FadeOutTransition(
						Color.black), new FadeInTransition(Color.black));
				enemyPokemon.setCurrentHp(enemyPokemon.getHp());
			}
		}
	}

	@Override
	public int getID() {
		return ID;
	}

}
